#pragma once

#include "messaging/dispatcher.h"
#include "messaging/server.h"
#include "filter.h"


namespace evm { namespace messaging {

/* A message dispatcher which understands Notification messages.
 * A MessageHandlingServer is constructed by passing a callable dispatcher
 * which is invoked with message dictionaries each time a message is received.
 * NotifcationDispatcher is one such dispatcher which pass a raw notification
 * message to the endpoints.
*/
struct NotificationDispatcher : BaseDispatcher {
    NotificationDispatcher(Targets targets, Endpoints endpoints);

    ListenerPtr listen(TransportPtr transport) {
        return transport->listen_for_notifications(targets_priorities);
    }

    void operator()(IncomingMsgPtr incoming);

private:
    using NofifyCallback = function<Json (const Json& args)>;

    bool dispatch(const Json &message);

    Targets targets;
    unordered_map<string, vector<pair<FilterPtr, NofifyCallback>>> callbacks_by_priority;
    vector<TargetPriority> targets_priorities;

    static const vector<string> PRIORITIES;
};

MessageServerPtr
get_notification_listener(TransportPtr transport, Targets targets, Endpoints endpoints);

}}
